using System;
using System.Concurrency;
using System.Disposables;
using System.Collections.Concurrent;

namespace Supremacy.Threading
{
/*
    public class InOrderScheduler : IScheduler
    {
        private readonly object _syncLock;
        private readonly ConcurrentQueue<Action> _queue;

        private bool _isRunning;

        public InOrderScheduler()
        {
            _queue = new ConcurrentQueue<Action>();
            _syncLock = new object();
        }

        public IDisposable Schedule(Action action)
        {
            if (action == null)
                throw new ArgumentNullException("action");

            var disposable = new BooleanDisposable();

            _queue.Enqueue(
                () =>
                {
                    if (!disposable.IsDisposed)
                        action();
                });

            Notify();
            
            return disposable;
        }

        public IDisposable Schedule(Action action, TimeSpan dueTime)
        {
            if (action == null)
                throw new ArgumentNullException("action");

            var span = Normalize(dueTime);
            var disposable = new CompositeDisposable(new IDisposable[0]);

            disposable.Add(Scheduler.ThreadPool.Schedule(() => disposable.Add(this.Schedule(action)), span));

            return disposable;
        }

        private void Run()
        {
            while (true)
            {
                Action action;

                lock (_syncLock)
                {
                    if (!_queue.TryDequeue(out action))
                    {
                        _isRunning = false;
                        break;
                    }
                }

                action();
            }
        }

        private void Notify()
        {
            var scheduleRun = false;

            lock (_syncLock)
            {
                if (!_isRunning && !_queue.IsEmpty)
                {
                    _isRunning = true;
                    scheduleRun = true;
                }
            }

            if (!scheduleRun)
                return;

            Scheduler.ThreadPool.Schedule(Run);
        }

        private static TimeSpan Normalize(TimeSpan timeSpan)
        {
            if (timeSpan.Ticks < 0L)
                return TimeSpan.Zero;
            return timeSpan;
        }

        public DateTimeOffset Now
        {
            get { return DateTimeOffset.Now; }
        }
    }
*/
}